home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / WINFONTS / FNTPRN.ZIP / FNTSRC.ZIP / ENUMFONT.C < prev    next >
Text File  |  1993-03-16  |  40KB  |  1,210 lines

  1. // Contents copyright (c) 1993 John Deurbrouck
  2. /*
  3. **  Define DEBUG for compilation under Borland C++ 3.1 to get a
  4. **  standalone test version of ENUMFONT.C
  5. */
  6. #ifdef DEBUG
  7. int wanna_quit=0;
  8. #endif
  9.  
  10. /*
  11. **  Includes
  12. */
  13. #include<windows.h>
  14. #include<stdio.h>
  15. #include<stdlib.h>
  16. #include<stdarg.h>
  17. #include<commdlg.h>
  18. #include<string.h>
  19. #include"enumfont.h"
  20.  
  21. /*
  22. **  Private Defines
  23. */
  24. #ifdef DEBUG
  25.     #define printf mprintf
  26. #endif
  27. #define FONTHASREGULAR      1
  28. #define FONTHASBOLD         2
  29. #define FONTHASITALIC       4
  30. #define FONTHASBOLDITALIC   8
  31. #define FONTISTRUETYPE     16
  32. #define FONTISFIXEDWIDTH   32
  33. #define MAXALLOCATIONS    100
  34. #define ALLOCATIONSIZE  32000
  35. #define MAXFONTS          512
  36.  
  37. /*
  38. **  Type Definitions
  39. */
  40. // TRACKFONT struct used to store font data
  41. typedef struct tagTRACKFONT{
  42.     LPSTR facename;
  43.     int flags;
  44.     int height;
  45.     int width;
  46.     int narrowness;
  47.     int weight;
  48.     BYTE fonttype;
  49.     LPSTR regular,bold,italic,bolditalic;
  50. }TRACKFONT,FAR* LPTRACKFONT;
  51. // TEXTQUEUE for linked list of .WRI file data
  52. typedef struct tagTEXTQUEUE{
  53.     LPSTR text;
  54.     int textlen;
  55.     void FAR* next;
  56. }TEXTQUEUE,FAR* LPTEXTQUEUE;
  57. // WRITEFILEHEADER used to write .WRI header
  58. typedef struct tagWRITEFILEHEADER{
  59.     int wIdent;
  60.     int dty;
  61.     int wTool;
  62.     int wReserved[4];
  63.     long fcMac;
  64.     int pnPara;
  65.     int pnFntb;
  66.     int pnSep;
  67.     int pnSetb;
  68.     int pnPgtb;
  69.     int pnFfntb;
  70.     int szSsht[33];
  71.     int pnMac;
  72.     int wReserved2[15];
  73. }WRITEFILEHEADER,FAR* LPWRITEFILEHEADER;
  74. // FOD for .WRI file generation
  75. typedef struct tagFOD{
  76.     long fcLim;
  77.     int bfprop;
  78. }FOD,FAR* LPFOD;
  79. // PAP for .WRI file paragraph data
  80. typedef struct tagPAP{
  81.     char len;
  82.     char res1;
  83.     char just;
  84. }PAP,FAR* LPPAP;
  85. // CHP3, CHP5 for .WRI file character information
  86. typedef struct tagCHP3{
  87.     char len;
  88.     char res1;
  89.     unsigned char bold_it_fontLSBs;
  90.     char fontsiz;
  91. }CHP3,FAR* LPCHP3;
  92. typedef struct tagCHP5{
  93.     char len;
  94.     char res1;
  95.     unsigned char bold_it_fontLSBs;
  96.     char fontsiz;
  97.     char uline;
  98.     unsigned char fontMSBs;
  99. }CHP5,FAR* LPCHP5;
  100.  
  101. /*
  102. **  Global Variables
  103. */
  104. HANDLE instance=0;
  105. HWND hwndSortorder;
  106. HWND hwndDialog;
  107. /* following are user choices to drive file generation */
  108. SORTORDER sortorder=ALPHA;
  109. MONOSPACE monospace=VARMONO;
  110. int use_printer_context=0,allow_synthesis=0,truetype_only=0;
  111. int incl_novelty=0,incl_modern=0,incl_roman=0,
  112.    incl_script=0,incl_sanserif=0,incl_other=0;
  113. int incl_regular=0,incl_bold=0,incl_italic=0,incl_bolditalic=0;
  114. int launchwrite=0;
  115. /* following are for internal use of generate_file_from_options() */
  116. static int successful_so_far,did_bailout;// error-occurred variable
  117. static OPENFILENAME ofn;
  118. static HFILE file=HFILE_ERROR;
  119. static int fams;                        // font families in fonts
  120. static LPTRACKFONT fonts[MAXFONTS];
  121. static HDC hdc;
  122. static FONTENUMPROC do_families,do_individuals;
  123. /* following are for use of get_memory() and free_memory() */
  124. static HGLOBAL mem_handles[MAXALLOCATIONS];
  125. static int mem_handles_used=0,memory_system_restart=0;
  126. // following set by dialog proc, used by generate_file_from_options()
  127. LPSTR sample_text_ptr=0;
  128. int sample_text_length=0;
  129. int sample_text_pointsize=0;       // in half-points (24==12pt)
  130. int sample_text_just=0;            // JUST_LEFT ... JUST_JUST
  131. LPSTR default_font=0;
  132. BYTE default_ffid=0;
  133. int default_pointsize=0;           // in half-points (24==12 pt)
  134. int default_just=0;                // JUST_LEFT ... JUST_JUST
  135. int default_bolditalic=0;          // BOLD_BIT | ITALIC_BIT
  136. // generate_file_from_options() sets and uses for .WRI file:
  137. LPTEXTQUEUE text_first,text_last;
  138. LPTEXTQUEUE char_first,char_last;
  139. LPTEXTQUEUE graf_first,graf_last;
  140. LPTEXTQUEUE font_first,font_last;
  141. long text_bytes,char_pages,graf_pages,font_pages;
  142. int default_font_offset;                // font code for default txt
  143.  
  144. /*
  145. **  Function Prototypes
  146. */
  147. int PASCAL WinMain(HANDLE hInstance,HANDLE hPrevInst,LPSTR cmd,int Show);
  148. static void bailout(char *msg);
  149. int CALLBACK _export families(LPENUMLOGFONT lpelf,TEXTMETRIC FAR* tmptr,
  150.     int fonttype,LPARAM lparam);
  151. static LPSTR get_font_type(BYTE pitchandfamily);
  152. int CALLBACK _export individuals(LPENUMLOGFONT lpelf,TEXTMETRIC FAR* tmptr,
  153.     int fonttype,LPARAM lparam);
  154. #ifdef DEBUG
  155. int mprintf(const char *fmt,...);
  156. #endif
  157. static void open_output_file(void);
  158. static void gather_data(void);
  159. static void sort_data(void);
  160. static int sorter(const void* arg1,const void* arg2);
  161. static void FAR* get_zeroed_memory(size_t size);
  162. static void FAR* get_memory(size_t size);
  163. static void free_memory(void);
  164. static void generate_report(void);
  165. static void w_init(void);
  166. static void w_default(const char* fmt,...);
  167. static void w_sample(LPTRACKFONT lpf,int bolditalic);
  168. static int w_add_font(LPSTR name, BYTE ffid);
  169. static void w_add_graf(int textlen,int just);
  170. static void w_add_char(int textlen,int bolditalic,int fontcode,int size);
  171. static void w_add_text(LPSTR text,int size);
  172. static void write_data_file(void);
  173. static int write_data_chunk(LPSTR buf,size_t buflen);
  174. static void create_device_context(void);
  175. static void get_user_options(void);
  176.  
  177. /*
  178. **  Function Definitions
  179. */
  180. #ifdef DEBUG
  181. #pragma argsused
  182. // test scaffolding
  183. int PASCAL WinMain(HANDLE hInstance,HANDLE hPrevInst,LPSTR cmd,int Show){
  184.     _InitEasyWin();
  185.     instance=hInstance;
  186.     for(;;){
  187.         get_user_options();
  188.         if(wanna_quit)break;
  189.         generate_file_from_options();
  190.     }
  191.     return 0;
  192. }
  193. #endif
  194.  
  195. void generate_file_from_options(void){
  196.     // initialize global variables
  197.     do_families=do_individuals=NULL;
  198.     hdc=NULL;
  199.     successful_so_far=1;
  200.     did_bailout=0;
  201.     fams=0;
  202.     // ok, let's get to work
  203.     if(successful_so_far)gather_data();
  204.     if(successful_so_far)sort_data();
  205.     if(successful_so_far)generate_report();
  206.     if(successful_so_far)open_output_file();
  207.     if(successful_so_far)write_data_file();
  208.     if(successful_so_far)bailout(NULL);
  209.     else SetFocus(hwndSortorder);
  210. }
  211.  
  212. // clean up, release memory, device context, etc.
  213. static void bailout(char *msg){
  214.     if(did_bailout)return;              // don't do this stuff twice
  215.     if(msg!=NULL){
  216.         MessageBox(hwndDialog,msg,"Error",MB_OK|MB_ICONEXCLAMATION);
  217.         successful_so_far=0;
  218.     }
  219.     if(hdc!=NULL){
  220.         DeleteDC(hdc);
  221.         hdc=NULL;
  222.     }
  223.     if(do_families!=NULL){
  224.         FreeProcInstance(do_families);
  225.         do_families=NULL;
  226.     }
  227.     if(do_individuals!=NULL){
  228.         FreeProcInstance(do_individuals);
  229.         do_individuals=NULL;
  230.     }
  231.     if(file!=HFILE_ERROR){
  232.         char buf[270];
  233.         _lclose(file);
  234.         file=HFILE_ERROR;
  235.         if(launchwrite&&successful_so_far){
  236.             wsprintf(buf,"WRITE %s",ofn.lpstrFile);
  237.             SetFocus(hwndSortorder);
  238.             WinExec(buf,SW_SHOWNORMAL);
  239.         }
  240.     }
  241.     free_memory();
  242. }
  243.  
  244. // families() is the callback function passed to EnumFontFamilies()
  245. // it's called for every font family. for each family of interest,
  246. // families() calls EnumFontFamilies() with individuals() as the
  247. // callback function. this gathers information on presence of
  248. // bold, italic, etc. and puts it into fonts[]
  249. #pragma argsused
  250. int CALLBACK _export families(LPENUMLOGFONT lpelf,TEXTMETRIC FAR* tmptr,
  251.     int fonttype,LPARAM lparam){
  252.     if(fams==MAXFONTS){
  253.         // only nine bits available for font number, so .WRI file
  254.         // can't have more than 512 fonts
  255.         MessageBox(hwndDialog,"Due to limitations in the .WRI format, "
  256.         "only working with first 512 font families.\n\n"
  257.         "Assemble several reports to list all your fonts.",
  258.             "Too many fonts",MB_OK|MB_ICONINFORMATION);
  259.         return 0;
  260.     }
  261.     // if we don't want non-TT, don't gather this one...
  262.     if(truetype_only&&!(fonttype&TRUETYPE_FONTTYPE))return 1;
  263.     // if we don't want this font type, don't gather it...
  264.     switch(lpelf->elfLogFont.lfPitchAndFamily&~3){
  265.     case FF_DECORATIVE: if(!incl_novelty)return 1;  break;
  266.     case FF_MODERN:     if(